package com.tbit.uqbike.client.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tbit.uqbike.client.constant.InviteConstant;
import com.tbit.uqbike.client.constant.NewEventConstant;
import com.tbit.uqbike.client.constant.RechargeConstant;
import com.tbit.uqbike.client.dao.core.CouponDao;
import com.tbit.uqbike.client.dao.core.CouponUserDao;
import com.tbit.uqbike.client.dao.core.InviteNewEventDao;
import com.tbit.uqbike.client.dao.core.UserMsgDao;
import com.tbit.uqbike.client.dao.log.InviteLogDao;
import com.tbit.uqbike.client.dao.log.InviteTotalDao;
import com.tbit.uqbike.client.exception.BaseException;
import com.tbit.uqbike.client.pojo.*;
import com.tbit.uqbike.client.remote.tenxun.AppletImageUtil;
import com.tbit.uqbike.client.service.*;
import com.tbit.uqbike.client.util.DateTimeUtil;
import com.tbit.uqbike.client.util.LogUtil;
import com.tbit.uqbike.client.util.TenpayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @Author: chen
 * @Description: 活动
 * @Date: 创建于 11:40 2020/12/31
 */
@Service
@Slf4j
public class InviteNewEventServiceImpl implements InviteNewEventService {
    @Autowired
    private InviteNewEventDao inviteNewEventDao;
    @Autowired
    private UserInvitationService userInvitationService;
    @Autowired
    private InvitationJoinService invitationJoinService;
    @Autowired
    private CouponUserDao couponUserDao;
    @Autowired
    private CouponDao couponDao;
    @Autowired
    private RideLogService rideLogService;
    @Autowired
    private EventDetailService eventDetailService;
    @Autowired
    private UserRewardLogService userRewardLogService;
    @Autowired
    private UserService userService;
    @Autowired
    private ActiveStatService activeStatService;
    @Autowired
    private WeixinPayService weixinPayService;
    @Autowired
    private WeixinPayConfigService weixinPayConfigService;
    @Autowired
    private UserMsgDao userMsgDao;
    @Autowired
    private RedisService redisService;
    @Autowired
    private InviteTotalDao inviteTotalDao;
    @Autowired
    private InviteLogDao inviteLogDao;

    private HashMap<Integer,String> typemap = new HashMap<Integer,String>() {{
        put(0, "完成接收分享-接收用户");
        put(1, "完成首骑-接收用户");
        put(2, "完成接收分享-发起用户");
        put(3, "完成首骑-发起用户");
    }};;

    @Override
    public InviteNewEvent getByAccountId(Integer accountId, Integer type) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("type", type);
        InviteNewEvent inviteNewEvent = inviteNewEventDao.getByAccountId(map);
        if (inviteNewEvent != null) {
            inviteNewEvent.setDetails(eventDetailService.getByEventId(inviteNewEvent.getInviteId()));
        }
        return inviteNewEvent;
    }

    @Override
    public InviteNewEvent getNewEvent(Integer accountId, Integer type, User user) {
        InviteNewEvent inviteNewEvent = getByAccountId(accountId, type);
        if (inviteNewEvent != null) {
            UserInvitation userInvitation = userInvitationService.getByUserId(user.getUserId(), inviteNewEvent.getInviteId());
            if (userInvitation == null) {
                String code = user.getUserId() + "" + TenpayUtil.buildRandom(6);
                inviteNewEvent.setEventUrl(inviteNewEvent.getEventUrl() + "?code=" + code);
                userInvitation = new UserInvitation();
                userInvitation.setAccountId(accountId);
                userInvitation.setCode(code);
                userInvitation.setEventId(inviteNewEvent.getInviteId());
                userInvitation.setUserId(user.getUserId());
                userInvitationService.add(userInvitation);
            } else {
                inviteNewEvent.setEventUrl(inviteNewEvent.getEventUrl() + "?code=" + userInvitation.getCode());
            }
            /**添加活动参数记录*/
            activeStatService.add(user, inviteNewEvent.getInviteId(), NewEventConstant.EVENT_TYPE_WATCH);
        }
        return inviteNewEvent;
    }

    @Override
    public InviteNewEvent getByCode(String code, Integer type, User user) {
        UserInvitation userInvitation = userInvitationService.getByCode(code);
        if (userInvitation == null) {
            throw new BaseException("-180002", "该邀请码不存在");
        }
        return getNewEvent(userInvitation.getAccountId(), type, user);
    }

    @Override
    @Transactional
    public void invite(String code, User user) {
        Integer userId = user.getUserId();
        UserInvitation userInvitation = userInvitationService.getByCode(code);
        if (userInvitation == null) {
            log.warn("该邀请码不存在" + code);
            return;
        }
        /**用户填入自己邀请码不参与活动*/
        if (userId.equals(userInvitation.getUserId())) {
            return;
        }
        InviteNewEvent inviteNewEvent = inviteNewEventDao.getByEventId(userInvitation.getEventId());
        if (inviteNewEvent == null) {
            log.warn("该邀请码不存在" + code);
            return;
        }
        if (inviteNewEvent.getEndTime().getTime() < new Date().getTime()) {
            log.warn("该邀请码已失效" + code);
            return;
        }
        List<Integer> integerList = new ArrayList<>();
        integerList.add(NewEventConstant.REWARD_TYPE_NEW_USER_RECEIVE);
        integerList.add(NewEventConstant.REWARD_TYPE_INVITE_RECEIVE);
        /**获取赠送详细*/
        List<EventDetail> eventDetails = eventDetailService.getByType(inviteNewEvent.getInviteId(),
                integerList);
        /**老用户不触发赠送*/
        List<RideLog> rideLogs = rideLogService.getByUserId(userId);
        if (rideLogs.size() > 0) {
            log.warn("老用户参与活动不触发赠送" + user.getPhone() + ",用户id=" + userId);
            return;
        }
        /**判断是否已经被邀请过，已经邀请过的不在重复触发*/
        InvitationJoin invitationJoinDB = invitationJoinService.getByUserIdAndType(userId, InviteConstant.EVENT_INVITATION);
        if (invitationJoinDB != null) {
            log.warn("用户已经参与活动不触发赠送" + user.getPhone() + ",用户id=" + userId);
            return;
        }
        /**添加用户接受邀请信息*/
        Date date = new Date();
        /**查询用户是否存在邀请这个用户的记录*/
        boolean isOld = false;
        List<InvitationJoin> joins = invitationJoinService.getByInviteId(inviteNewEvent.getInviteId(), userInvitation.getUserId());
        if (joins.size() > 0) {
            isOld = true;
        }

        InvitationJoin invitationJoin = new InvitationJoin();
        invitationJoin.setAdAccountId(userInvitation.getAccountId());
        invitationJoin.setAccountId(user.getAccountId());
        invitationJoin.setEventId(userInvitation.getEventId());
        invitationJoin.setInviteUserId(userInvitation.getUserId());
        /**查询邀请用户信息*/
        User userDB = userService.getByUserId(userInvitation.getUserId());
        invitationJoin.setInvitePhone(userDB.getPhone());
        invitationJoin.setInviteName(userDB.getName());
        invitationJoin.setPhone(user.getPhone());
        invitationJoin.setUserId(userId);
        invitationJoin.setReceiveTime(date);
        invitationJoin.setEndTime(DateTimeUtil.addDay(date, inviteNewEvent.getValidDay()));
        invitationJoin.setType(InviteConstant.EVENT_INVITATION);
        invitationJoin.setState(NewEventConstant.INVITATIONJOIN_STATE_DEFAULT);
        invitationJoinService.add(invitationJoin);
        /**添加活动参数记录*/
        activeStatService.add(user, inviteNewEvent.getInviteId(), NewEventConstant.EVENT_TYPE_RECEIVE);
        if (eventDetails.size() > 0) {
            for (EventDetail e : eventDetails) {
                User inviteUser = user;
                if (e.getType().equals(NewEventConstant.REWARD_TYPE_INVITE_RECEIVE)) {
                    inviteUser = userDB;
                    /**已存在邀请关系的邀请人不触发赠送*/
                    if (isOld) {
                        log.warn("用户已邀请该新用户" + user.getPhone() + ",用户id=" + inviteUser.getUserId());
                        continue;
                    }
                    /**判断是否达到了赠送上限,达到赠送上限不在触发赠送*/
                    Integer count = invitationJoinService.getUserCount(userInvitation.getUserId(), userInvitation.getEventId());
                    if (count > e.getFrequency()) {
                        log.warn("用户参与活动达到上限" + user.getPhone() + ",用户id=" + inviteUser.getUserId());
                        continue;
                    }
                }
                /**开始赠送*/
                //todo 用户邀请新用户注册赠送
                couponGive(e, inviteUser, userInvitation.getAccountId(), date, inviteNewEvent.getName());
            }
        }
    }

    @Override
    public List<InvitationJoin> getUserEventLog(String code, Integer userId) {
        UserInvitation userInvitation = userInvitationService.getByCode(code);
        if (userInvitation == null) {
            throw new BaseException("-180002", "该邀请码不存在");
        }
        /**只能查看自己的记录*/
        if (!userInvitation.getUserId().equals(userId)) {
            return null;
        }
        return invitationJoinService.getByEventId(userInvitation.getUserId(), userInvitation.getEventId());
    }

    @Override
    public InviteNewEvent getByEventId(Integer eventId) {
        return inviteNewEventDao.getByEventId(eventId);
    }

    /**
     * 赠送优惠券
     *
     * @param e         活动赠送详情
     * @param user      赠送用户id
     * @param accountId 区域id
     * @param date      日期
     */
    @Override
    public void couponGive(EventDetail e, User user, Integer accountId, Date date, String name) {
        Integer userId = user.getUserId();
        /**赠送礼品*/
        Coupon coupon = couponDao.getByCouponId(e.getRewardId());
        if (coupon != null) {
            List<CouponUser> list = new ArrayList<>();
            for (int i = 0; i < e.getRewardNum(); i++) {
                CouponUser couponUser = new CouponUser();
                couponUser.setUserId(userId);
                couponUser.setRecTime(DateTimeUtil.DateTimeToString(date));
                couponUser.setIsValid(1);
                couponUser.setIsUse(0);
                couponUser.setCouponId(e.getRewardId());
                couponUser.setAccountId(accountId);
                couponUser.setExpireTime(DateTimeUtil.DateTimeToString(DateTimeUtil.addDay(date, e.getValidDay())));
                list.add(couponUser);
            }
            if (list.size() > 0) {
                LogUtil.info("新用户邀请活动赠送userId=" + userId);
                couponUserDao.addBatch(list);
                /**记录用户获取奖励日志*/
                UserRewardLog userRewardLog = new UserRewardLog();
                userRewardLog.setUserId(userId);
                userRewardLog.setAdAccountId(accountId);
                userRewardLog.setEventId(e.getInviteId());
                userRewardLog.setRewardId(e.getRewardId());
                userRewardLog.setRewardNum(e.getRewardNum());
                userRewardLog.setRewardType(e.getGiveType());
                userRewardLog.setType(e.getType());
                userRewardLog.setRemark(typemap.get(e.getType()));
                userRewardLog.setInviteName(user.getName());
                userRewardLog.setInvitePhone(user.getPhone());
                userRewardLog.setRewardName(coupon.getName());
                userRewardLog.setEventType(InviteConstant.EVENT_INVITATION);
                userRewardLog.setEventName(name);
                userRewardLog.setAccountId(user.getAccountId());
                userRewardLogService.add(userRewardLog);
                /**小程序内部消息告知用户*/
                UserMsg userMsg = new UserMsg();
                userMsg.setMsgState(0);
                userMsg.setMsgType(0);
                userMsg.setUserId(userId);
                userMsg.setTitle("邀请新用户奖励通知");
                userMsg.setContent("您已获得赠送奖励,请注意查看");
                userMsg.setCreateTime(DateTimeUtil.getNowTime());
                userMsgDao.add(userMsg);
            }
        } else {
            LogUtil.info("优惠券不存在" + e.getRewardId());
        }

    }


    @Override
    public String createQrcode(User user, String code) {
        UserInvitation userInvitation = userInvitationService.getByCode(code);
        if (userInvitation == null) {
            throw new BaseException("-180002", "该邀请码不存在");
        }
        /**只能查看自己的记录*/
        if (!userInvitation.getUserId().equals(user.getUserId())) {
            System.out.println("用户不一致");
            return null;
        }
        WeixinPayConfig weixinPayConfig = weixinPayConfigService.getByAccountId(user.getAccountId(),
                RechargeConstant.RECHARGE_WEIXIN_XCX);
        String accessToken = weixinPayService.getAccessToken(weixinPayConfig);
        code = "code=" + code;
        String data = AppletImageUtil.createQrcode(accessToken, "pages/invitePage/invitePage", code);
        /**无效token清除缓存中token*/
        if (data.contains("errcode")) {
            JSONObject jsonObject = JSON.parseObject(data);
            if (jsonObject.getString("errcode").equals("40001")) {
                redisService.del("AccessToken" + weixinPayConfig.getAccountId());
            }
        }
        return data;
    }

}
